package com.glaciervirtualdevice.quart;

import com.glaciervirtualdevice.dto.THDateDTO;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * @Author: Sun
 * @DateTime: 2025/4/1 15:13
 * @Description: 温湿度调度工具类，使用 Quartz 框架实现定时生成温湿度数据并存储。
 **/
@Component
public class WarmHumidQuartz {
    // Quartz 调度器实例，用于管理
    // 定时任务
    @Autowired
    private Scheduler scheduler;
    // 用于存储每个组的最新温湿度信息，键为组名，值为 THDateDTO 对象
    private static final Map<String, THDateDTO> groupResults = new HashMap<>();
    // 用于生成随机数的 Random 对象
    private static final Random random = new Random();

    // 私有构造函数，防止外部实例化该类，确保该类以工具类的形式使用
    private WarmHumidQuartz() {
    }

    /**
     * 开启一个新的温湿度生成任务
     *
     * @param sn           任务组名，也是设备的唯一标识
     * @param standardTemp 标准温度
     * @param standardHum  标准湿度
     * @param intervalCron 任务执行的时间间隔（Cron 表达式）
     */
    public void startDevice(String sn, int standardTemp, int standardHum, String intervalCron) {
        try {
            // 获取 Quartz 调度器的默认实例
//            scheduler = StdSchedulerFactory.getDefaultScheduler();

            // 检查任务是否已经存在
//            GroupMatcher<JobKey> matcher = GroupMatcher.groupEquals(sn);
//            for (JobKey jobKey : scheduler.getJobKeys(matcher)) {
//                if (jobKey.getName().equals("WarmHumidJob_" + sn)) {
//                    // 任务已经存在，直接返回
//                    return;
//                }
//            }

            // 创建一个 JobDetail 对象，指定要执行的任务类为 WarmHumidJob
            JobDetail job = JobBuilder.newJob(WarmHumidJob.class)
                    .withIdentity("WarmHumidJob_" + sn, sn)
                    .usingJobData("warmDate", standardTemp)
                    .usingJobData("humidDate", standardHum)
                    .build();

            // 创建一个 Trigger 对象，设置任务的执行计划为按照 intervalCron 对应的 Cron 表达式执行，无限循环
            Trigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity("WarmHumidTrigger_" + sn, sn)
                    .withSchedule(CronScheduleBuilder.cronSchedule(intervalCron))
                    .build();

            // 将任务和触发器注册到调度器中
            scheduler.scheduleJob(job, trigger);
            // 启动调度器
            scheduler.start();

            // 开启任务时立即生成一个温湿度数据
            generateAndStoreData(sn, standardTemp, standardHum);
        } catch (SchedulerException e) {
            // 打印调度器异常信息
            e.printStackTrace();
        }
    }

    private  void generateAndStoreData(String sn, int standardTemp, int standardHum) {
        int temperature = random.nextInt(11) + standardTemp - 5;
        int humidity = random.nextInt(11) + standardHum - 5;
        THDateDTO result = new THDateDTO();
        result.setHum(humidity);
        result.setTem(temperature);
        storeGroupResult(sn, result);
    }

    /**
     * 根据组名获取最新的温湿度信息
     * 先检查是否存在对应组名的任务，有则返回温湿度，没有则返回 null
     *
     * @param groupName 组名，用于标识要获取的温湿度信息
     * @return 该组的最新温湿度信息，封装在 THDateDTO 对象中，若不存在对应任务则返回 null
     */
    public THDateDTO getTemperatureHumidityByGroup(String groupName) {
        try {
            if (scheduler != null && !scheduler.isShutdown()) {
                // 获取所有任务组
                GroupMatcher<JobKey> matcher = GroupMatcher.groupEquals(groupName);
                for (JobKey jobKey : scheduler.getJobKeys(matcher)) {
                    if (jobKey.getGroup().equals(groupName)) {
                        return groupResults.get(groupName);
                    }
                }
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 结束任务
     *
     * @param groupName 要停止的任务组名
     */
    public void stopDevice(String groupName) {
        TriggerKey triggerKey = TriggerKey.triggerKey("WarmHumidTrigger_" + groupName, groupName);
        try {
            if (scheduler != null && !scheduler.isShutdown()) {
                scheduler.pauseTrigger(triggerKey);
                scheduler.unscheduleJob(triggerKey);
                scheduler.deleteJob(JobKey.jobKey("WarmHumidJob_" + groupName, groupName));
            }
        } catch (SchedulerException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 存储每个组的最新温湿度信息。
     *
     * @param groupName 组名，用于标识要存储的温湿度信息
     * @param result    该组的最新温湿度信息，封装在 THDateDTO 对象中
     */
    public static void storeGroupResult(String groupName, THDateDTO result) {
        // 将该组的温湿度信息存储到结果映射中
        groupResults.put(groupName, result);
    }
}